#include <kernel/multiboot/MultibootInfo.hpp>
#include <cpp/Printer.hpp>
#include <cpp/new.hpp>
#include <cpp/abort.hpp>
#include <kernel/Kernel.hpp>

Kernel* Kernel::_instance{nullptr};

Kernel::Kernel(const multiboot::MemoryMap& memoryMap, AbstractKeyboardDriver& keyboardDriver):
	_pageTableManager{memoryMap},
	_heapAddress{_pageTableManager.allocatePage()},
	_heapManagerPoolAllocator{_heapManagerPool},
	_heapManager{_heapAddress, _heapAddress == nullptr ? 0UL : _heapSize,
	             _heapManagerPoolAllocator},
	_keyboardDriver{keyboardDriver}
{
	_instance = this;
	printPrettyAsciiArt();
}

void Kernel::run()
{
	while(true)
		while(not _keyboardDriver.characterQueueEmpty())
			out << _keyboardDriver.getCharacter();
}

Kernel& Kernel::getInstance()
{
	return *_instance;
}

MemoryManager& Kernel::getHeapManager()
{
	return _heapManager;
}

void Kernel::printPrettyAsciiArt() const
{
	out << "\
\n\
\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\
\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\
\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\
\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\
\n\
                         \xCD\xCD\xCD\xCD\xCD\xCD\xCD\
						\xCD\xCD\xCD\xCD\xCD\xCD\xCD\
							\xCD\xCD\xCD\xCD\xCD\xCD\xCD\  Stroustrup powered\
\n\
\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\
\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\
\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\
\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\
\n\
";
}
